#pragma once
#include <DirectXMath.h>
#include <initializer_list>
namespace GMath
{
	class Vector3;
	class Matrix;
	class Vector2
	{
	public:
		float mData[2] = {};

		Vector2(float uniformValue)
		{
			mData[0] = mData[1] = uniformValue;
		}
		Vector2(std::initializer_list<float> data);
		Vector2() {
			mData[0] = mData[1] = 0;
		};

		Vector2(float data[2]);
		float operator[](int i)const;
		float& operator[](int i);
		Vector2 operator*(float f)const;
		Vector2 operator-(const Vector2& rhs)const;
		Vector2 operator+(const Vector2& rhs)const;
	};
	class Vector4
	{
	public:
		float mData[4] = {};
	public:
		Vector4(std::initializer_list<float> data);
		Vector4(const Vector3& data, float z = 0.0f);
		Vector4() {
			mData[0] = mData[1] = mData[2] = mData[3] = 0;
		};
		void operator=(const Vector3& vec3);
		float operator[](int i)const;
		float& operator[](int i);

		Vector4 operator*(float f)const;
		Vector4 operator*(const Matrix& mat);
		Vector4 operator-(const Vector4& rhs)const;
		Vector4 operator+(const Vector4& rhs)const;

		Vector4 Normalize()const;
	};
	class Vector3
	{
	public:
		float mData[3];
	public:
		explicit  Vector3(float uniformValue)
		{
			mData[0] = mData[1] = mData[2] = uniformValue;
		}
		Vector3(std::initializer_list<float> data);
		Vector3() {
			mData[0] = mData[1] = mData[2] = 0;
		};
		Vector3(DirectX::XMFLOAT3 data)
		{
			mData[0] = data.x;
			mData[1] = data.y;
			mData[2] = data.z;
		}
		Vector3(float data[3]);
		Vector3(const Vector4& data);
		float operator[](int i)const;
		float& operator[](int i);
		Vector3 operator*(const Vector3& rhs)const;
		Vector3 operator*(float f)const;
		Vector3 operator/(float f)const;
		Vector3 operator-()const;
		Vector3 operator-(const Vector3& rhs)const;
		Vector3 operator+(const Vector3& rhs)const;
		Vector3 operator+=(const Vector3& rhs);
		bool operator<(const Vector3& rhs)const;
		bool operator>(const Vector3& rhs)const;
		float Length()const ;
		Vector3 Normalize()const;
		Vector3 Cross(const Vector3& rhs)const;
		float Dot(const Vector3& rhs)const;
	};

	class Matrix
	{
	public:
		DirectX::XMFLOAT4X4 mData;

	public:
		Matrix() = default;

		static Matrix Translation(Vector3 trans);

		static Matrix RotationPitchYawRoll(Vector3 rotation);

		static Matrix Scale(Vector3 scale);

		Matrix Inverse()const;

		Matrix Transpose()const;

		Vector4 operator[](int i);

		static Matrix TRS(Vector3 trans, Vector3 rotation, Vector3 scale);
	public:
		Matrix(DirectX::XMFLOAT4X4 data) :mData(data) {};
	};
};

